package com.bao.lc.proxy;
/*
* This file is part of the OWASP Proxy, a free intercepting proxy library.
* Copyright (C) 2008-2010 Rogan Dawes <rogan@dawes.za.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to:
* The Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
import com.bao.lc.proxy.IEProxy.WinInet.INTERNET_PER_CONN_OPTION;
import com.bao.lc.proxy.IEProxy.WinInet.INTERNET_PER_CONN_OPTION_LIST;
import com.sun.jna.LastErrorException;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Union;
import com.sun.jna.ptr.LongByReference;
/**
* Picked up from OWASP
* Original name: org.owasp.proxy.util.WindowsProxy
*/
public class IEProxy
{
public static class ProxySettings
{
public int flags = 0;
public String proxyServer = null;
public String proxyBypass = null;
public String autoConfigUrl = null;
public int autoDiscoveryFlags = 0;
private int set(int flags, int mask, boolean value)
{
if(value)
return flags | mask;
return flags & ~mask;
}
public boolean isAutoProxy()
{
return (flags & WinInet.PROXY_TYPE_AUTO_PROXY_URL) > 0;
}
public void setAutoProxy(boolean value)
{
flags = set(flags, WinInet.PROXY_TYPE_AUTO_PROXY_URL, value);
}
public boolean isAutoDetect()
{
return (flags & WinInet.PROXY_TYPE_AUTO_DETECT) > 0;
}
public void setAutoDetect(boolean value)
{
flags = set(flags, WinInet.PROXY_TYPE_AUTO_DETECT, value);
}
public boolean isDirect()
{
return (flags & WinInet.PROXY_TYPE_DIRECT) > 0;
}
public void setDirect(boolean value)
{
flags = set(flags, WinInet.PROXY_TYPE_DIRECT, value);
}
public boolean isProxy()
{
return (flags & WinInet.PROXY_TYPE_PROXY) > 0;
}
public void setProxy(boolean value)
{
flags = set(flags, WinInet.PROXY_TYPE_PROXY, value);
}
public String toString()
{
return getClass().getSimpleName() + " (flags=" + flags + " (autoProxy=" + isAutoProxy()
+ ", autoDetect=" + isAutoDetect() + ", direct=" + isDirect() + ", proxy="
+ isProxy() + "), proxyServer=" + proxyServer + ", proxyBypass=" + proxyBypass
+ ", autoConfigUrl=" + autoConfigUrl + ", autoDiscoveryFlags=" + autoDiscoveryFlags
+ ")";
}
}
private static Error available = null;
private static WinInet wininet = null;
// private static CLibrary clibrary = null;
//
// public interface CLibrary extends Library {
//
// void free(Pointer p);
//
// }
static
{
try
{
wininet = (WinInet) Native.loadLibrary("wininet", WinInet.class);
// clibrary = (CLibrary) Native.loadLibrary("msvcrt",
// CLibrary.class);
}
catch(Error e)
{
available = e;
}
}
public static boolean isAvailable()
{
return available == null;
}
/**
* Invokes WinInet.InternetQueryOptionA to obtain Windows Proxy Settings
*
* @return a {@link ProxySettings} object containing the extracted values
* @throws LastErrorException
* if there is an error retrieving the settings
*/
public static ProxySettings getProxySettings() throws LastErrorException
{
if(available != null)
throw new RuntimeException("Unable to initialise JNA libraries", available);
INTERNET_PER_CONN_OPTION.ByReference optRef = new INTERNET_PER_CONN_OPTION.ByReference();
INTERNET_PER_CONN_OPTION[] options = (INTERNET_PER_CONN_OPTION[]) optRef.toArray(5);
options[0].dwOption = WinInet.INTERNET_PER_CONN_FLAGS;
options[1].dwOption = WinInet.INTERNET_PER_CONN_PROXY_SERVER;
options[2].dwOption = WinInet.INTERNET_PER_CONN_PROXY_BYPASS;
options[3].dwOption = WinInet.INTERNET_PER_CONN_AUTOCONFIG_URL;
options[4].dwOption = WinInet.INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
for(int i = 0; i < options.length; i++)
options[i].write();
INTERNET_PER_CONN_OPTION_LIST list = new INTERNET_PER_CONN_OPTION_LIST();
list.dwOptionCount = options.length;
list.dwOptionError = 0;
list.pOptions = optRef;
list.dwSize = list.size();
list.write();
LongByReference size = new LongByReference(list.size());
boolean result = wininet.InternetQueryOptionA(null,
WinInet.INTERNET_OPTION_PER_CONNECTION_OPTION, list.getPointer(), size);
if(!result)
{
System.out.println("Error: " + Native.getLastError());
System.out.println("Option error: " + list.dwOptionError);
return null;
}
else
{
ProxySettings settings = new ProxySettings();
list.read();
for(int i = 0; i < options.length; i++)
{
switch(options[i].dwOption)
{
case WinInet.INTERNET_PER_CONN_FLAGS:
settings.flags = getInt(options[i]);
break;
case WinInet.INTERNET_PER_CONN_PROXY_SERVER:
settings.proxyServer = getString(options[i]);
break;
case WinInet.INTERNET_PER_CONN_PROXY_BYPASS:
settings.proxyBypass = getString(options[i]);
break;
case WinInet.INTERNET_PER_CONN_AUTOCONFIG_URL:
settings.autoConfigUrl = getString(options[i]);
break;
case WinInet.INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
settings.autoDiscoveryFlags = getInt(options[i]);
break;
}
}
return settings;
}
}
private static String getString(INTERNET_PER_CONN_OPTION option)
{
option.value.setType(Pointer.class);
option.value.read();
if(option.value.pszValue == null)
return null;
String str = option.value.pszValue.getString(0);
// FIXME : We still need to free this memory somehow!?
// clibrary.free(option.value.pszValue);
return str;
}
private static int getInt(INTERNET_PER_CONN_OPTION option)
{
option.value.setType(int.class);
option.value.read();
return option.value.dwValue;
}
public static void setProxySettings(ProxySettings settings)
{
if(available != null)
throw new RuntimeException("Unable to initialise JNA libraries", available);
INTERNET_PER_CONN_OPTION.ByReference optRef = new INTERNET_PER_CONN_OPTION.ByReference();
INTERNET_PER_CONN_OPTION[] options = (INTERNET_PER_CONN_OPTION[]) optRef.toArray(5);
options[0].dwOption = WinInet.INTERNET_PER_CONN_FLAGS;
options[0].value.setType(int.class);
options[0].value.dwValue = settings.flags;
options[1].dwOption = WinInet.INTERNET_PER_CONN_PROXY_SERVER;
options[1].value.setType(String.class);
options[1].value.strValue = settings.proxyServer;
options[2].dwOption = WinInet.INTERNET_PER_CONN_PROXY_BYPASS;
options[2].value.setType(String.class);
options[2].value.strValue = settings.proxyBypass;
options[3].dwOption = WinInet.INTERNET_PER_CONN_AUTOCONFIG_URL;
options[3].value.setType(String.class);
options[3].value.strValue = settings.autoConfigUrl;
options[4].dwOption = WinInet.INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
options[4].value.setType(int.class);
options[4].value.dwValue = settings.autoDiscoveryFlags;
for(int i = 0; i < options.length; i++)
options[i].write();
INTERNET_PER_CONN_OPTION_LIST list = new INTERNET_PER_CONN_OPTION_LIST();
list.dwOptionCount = options.length;
list.dwOptionError = 0;
list.pOptions = optRef;
list.dwSize = list.size();
list.write();
if(!wininet.InternetSetOptionA(null, WinInet.INTERNET_OPTION_PER_CONNECTION_OPTION,
list.getPointer(), list.size()))
throw new RuntimeException("Error invoking InternetSetOptionA, code "
+ Native.getLastError());
}
public static void main(String[] args)
{
ProxySettings current = getProxySettings();
System.out.println(current + "\n\n");
ProxySettings replacements = new ProxySettings();
replacements.proxyServer = "https=localhost:3212;socks=localhost:1081";
replacements.setProxy(true);
replacements.setDirect(true);
setProxySettings(replacements);
System.out.println(getProxySettings() + "\n\n");
setProxySettings(current);
System.out.println(getProxySettings());
}
// bizarrely, use of an import for this Library symbol fails the build in
// Maven
interface WinInet extends com.sun.jna.Library
{
/**
* PER_CONN_FLAGS
*/
/**
* Specifies that some connections may be made directly to the server,
* bypassing the proxy
*/
static int PROXY_TYPE_DIRECT = 0x00000001; // direct to net
/**
* Specifies that some connections may go via a proxy
*/
static int PROXY_TYPE_PROXY = 0x00000002; // via named proxy
/**
* Not sure exactly what this one does. Maybe that a .pac file is
* active?
*/
static int PROXY_TYPE_AUTO_PROXY_URL = 0x00000004; // autoproxy
// URL
/**
* Specifies that the browser will auto detect the proxy, according to
* the MS auto-detect methodology
*/
static int PROXY_TYPE_AUTO_DETECT = 0x00000008; // use autoproxy
// detection
//
// Options used in INTERNET_PER_CONN_OPTON struct
//
static int INTERNET_PER_CONN_FLAGS = 1;
static int INTERNET_PER_CONN_PROXY_SERVER = 2;
static int INTERNET_PER_CONN_PROXY_BYPASS = 3;
static int INTERNET_PER_CONN_AUTOCONFIG_URL = 4;
static int INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5;
//
// PER_CONN_AUTODISCOVERY_FLAGS
//
// user changed this setting
static int AUTO_PROXY_FLAG_USER_SET = 0x00000001;
// force detection even when its not needed
static int AUTO_PROXY_FLAG_ALWAYS_DETECT = 0x00000002;
// detection has been run
static int AUTO_PROXY_FLAG_DETECTION_RUN = 0x00000004;
// migration has just been done
static int AUTO_PROXY_FLAG_MIGRATED = 0x00000008;
// don't cache result of host=proxy name
static int AUTO_PROXY_FLAG_DONT_CACHE_PROXY_RESULT = 0x00000010;
// don't initalize and run unless URL expired
static int AUTO_PROXY_FLAG_CACHE_INIT_RUN = 0x00000020;
// if we're on a LAN & Modem, with only one IP, bad?!?
static int AUTO_PROXY_FLAG_DETECTION_SUSPECT = 0x00000040;
static int INTERNET_OPTION_PER_CONNECTION_OPTION = 75;
boolean InternetQueryOptionA(Pointer unused, int dwOption, Pointer lpBuffer,
LongByReference size);
boolean InternetSetOptionA(Pointer unused, int dwOption, Pointer buffer, int bufferLength);
boolean InternetQueryOptionW(Pointer unused, int dwOption, Pointer lpBuffer,
LongByReference size);
boolean InternetSetOptionW(Pointer unused, int dwOption, Pointer buffer, int bufferLength);
public static class INTERNET_PER_CONN_OPTION extends Structure
{
public int dwOption;
public static class FILETIME extends Structure
{
public int dwLowDateTime;
public int dwHighDateTime;
}
public static class Value extends Union
{
public int dwValue;
public Pointer pszValue;
public FILETIME ftValue;
public String strValue;
}
public Value value;
public static class ByReference extends INTERNET_PER_CONN_OPTION implements
Structure.ByReference
{
};
}
public static class INTERNET_PER_CONN_OPTION_LIST extends Structure
{
public int dwSize;
public Pointer pszConnection;
public int dwOptionCount;
public int dwOptionError;
public INTERNET_PER_CONN_OPTION.ByReference pOptions;
}
}
}